package exam;

//https://blog.csdn.net/weixin_39588432/article/details/114056922
//https://blog.csdn.net/yijianqingyu/article/details/125485830

/**
 * 实现一个路由转发模块，转发模块的核心功能之一是根据功能号/接口名来
 * 进行路由转发。路由四配的基本原理是判断实际请求中的功能号/接口名是否与预先配置的转发规则四配，
 * 转发规则支持'?’和'*’通配符(?表示匹配任意单个字符;表示匹配零个或多个任意字符)。
 * 比如转发规则串配置为“600???"，当实际请求中的功能号是“600570”时就判定为四配。
 *
 * 注意:要自己编码实现逻辑，不可以调用已有的实现函数。
 * 1.实际请求中的功能号/接口名只包含从0-9的数字或者a-z的英文字母(大小写敏感)
 * 2.预定义的模式四配串只包含从0-9的数字，a-z的字母(大小写敏感)以及字符?”和
 *
 * 程序输入输出要求说明
 * 输入参数分为两行，第一行是功能号/接口名;第二行是匹配规则串。输出参数:如果匹配，则输出字符串"true"，否则输出"false”。
 * 示例   输入: aa a   输出: false
 */
public class 路由 {

    public static void main(String[] args) {
        boolean path = isMatch("600a70", "600??");
        boolean path2 = isMatch("6005A", "600*");
        System.out.println(path);
        System.out.println(path2);
    }

    /**
     * 1、定义function、rule的索引下标、通配符回溯的位置
     * 2、遍历function
     * 3、rule_i索引 < rule.length, rule_i == *，即遇到通配符，则
     *                  function_jj = function_i;
     *                  role_jj = rule_i;
     *                  rule_i++;
     * 4、rule_i索引 < rule.length，，function与rule 相等或遇到？
     *                  function_i++;
     *                  rule_i++;
     * 5、当前面匹配失败， role_jj == -1没有通配符直接匹配失败
     *                  rule_i = role_jj;   回到之前记录通配符的位置
     *                  function_i = function_jj + 1;   回到之前记录通配符的位置
     * 5、当function全部字符都匹配成功后，判断role剩下的串是否为 *， 是时 rule_i++;
     * 6、return rule_i == rule.length , 则匹配成功
     *
     * @param function 待匹配的字符串
     * @param rule 匹配规则
     * @return
     */
    public static Boolean isMatch(String function, String rule) {
        //s的索引位置
        int function_i = 0;
        //p的索引位置
        int rule_i = 0;
        //通配符时回溯的位置
        int function_jj = -1;
        int role_jj = -1;
        while (function_i < function.length()) {
            if (rule_i < rule.length() && rule.charAt(rule_i) == '*') {
                //遇到通配符了,记录下位置,规则字符串+1,定位到非通配字符串
                function_jj = function_i;
                role_jj = rule_i;
                rule_i++;
            } else if (rule_i < rule.length() && (function.charAt(function_i) == rule.charAt(rule_i) || rule.charAt(rule_i) == '?')) {
                //匹配到了
                function_i++;
                rule_i++;
            } else {
                //匹配失败,需要判断function 是否被role的*号匹配着
                //前面没有通配符
                if (role_jj == -1) {
                    return false;
                }
                //回到之前记录通配符的位置
                rule_i = role_jj;
                //待匹配字符串也回到记录的位置,并后移一位
                function_i = function_jj + 1;
            }
        }
        //当function的每一个字段都匹配成功以后,判断 role 剩下的串,是*则放行
        while (rule_i < rule.length() && rule.charAt(rule_i) == '*') {
            rule_i++;
        }
        //检测到最后就匹配成功
        return rule_i == rule.length();
    }
}
